/*
 * WFont.java
 *
 * Created on 20 November 2007, 22:11
 *
 */

package net.ubinow.mflex.baseui;

import javax.microedition.lcdui.*;

/**
 *
 * @author Josh
 */
public class WFont {
    
    public static final int SIZE_SMALL              = 0;
    public static final int SIZE_BIG                = 1;    
    
    private static final int DEFAULT_MAGIC_SPACING  = 2;
    
    // large font details
    private Image _customFont;
    private int _lettersX[] = new int[256];
    private int _lettersY[] = new int[256];
    private int _xPadding[] = null;
    private boolean _capsOnly = true;
    private int _charWidth = 0;
    private int _charHeight = 0;
    private int _spacing=0;
    private int _magicSpacing = 0;
    private int _fontType = 0; // e.g. SMALL, LARGE
    private int _fontColour = 0; // e.g. COLOR_BLACK, COLOUR_WHITE etc
    
    public WFont(){
        _magicSpacing = DEFAULT_MAGIC_SPACING;
    }
    
    /**
     *
     * @param fontType: e.g. FONT_LARGE, FONT_SMALL etc
     * @param fontColour: e.g. COLOR_BLACK, COLOUR_WHITE etc
     * @param fontChars: character mapping to the png file (characters corresponding to the png file)
     * @param fontImage: png file containing the fonts
     * @param fontWidth: font width
     * @param fontHeight: font height
     * @param allCaps: set to true if the png file only have caps (if set to true then any small case will be converted to upper case)
     * @param xPadding: an array of x character offset paddings (e.g. will move the character depending on what the character is a specified/specified x pixel amount) - set to NULL if no adjustments are required
     */
    public void initFont( int fontType, int fontColour, String fontChars, Image fontImage, int fontWidth, int fontHeight, boolean allCaps, int[] xPadding ) {
        _fontType = fontType;
        _fontColour = fontColour;
        
        _customFont = fontImage;
        _capsOnly=allCaps;
        _charWidth = fontWidth;
        _spacing=_charWidth;
        _charHeight = fontHeight;
        
        if( xPadding != null )
            _xPadding = new int[256];
        
        byte charBytes[] = fontChars.getBytes();
        int charsPerRow = (int)(fontImage.getWidth()/fontWidth);
        int columnCharCount = 0;
        int Xtrans=0;
        int Ytrans=0;
        int ASCIIval=0;
        for (int i=0; i<charBytes.length; i++) {
            ASCIIval=(0|charBytes[i])&0xFF;
            _lettersX[ASCIIval]=Xtrans;
            _lettersY[ASCIIval]=Ytrans;
            if( xPadding != null )
                _xPadding[ASCIIval] = xPadding[i];
            columnCharCount++;
            if (columnCharCount>=charsPerRow) {
                Xtrans=0;
                Ytrans+=fontHeight;
                columnCharCount=0;
            } else Xtrans+=fontWidth;
            
        }
    }
    
    public void drawString( Graphics gC, String plotString, int plotX, int plotY ) {
        int clipX = gC.getClipX();
        int clipY = gC.getClipY();
        int clipW = gC.getClipWidth();
        int clipH = gC.getClipHeight();

        // TODO: do a little more work on here - purpose is to check that the font is in view
        // a issue occurs when the the parent container clips the graphics when the fonts are 
        // draw they're visible becuase they 're-clip' the graphics object
        // - make sure the text is visible (ie hasn't been clipped out) before drawing it
        if( clipY+clipH < plotY )
            return;
        
        if (_capsOnly)
            plotString = plotString.toUpperCase();
        byte charBytes[] = plotString.getBytes();
        int ASCIIval=0;
        for (int i=0; i<charBytes.length; i++) {
            ASCIIval=(0|charBytes[i])&0xFF;
            if( ASCIIval != 32 ){
                gC.setClip(plotX, plotY, _charWidth, _charHeight);
                gC.drawImage(_customFont, plotX-_lettersX[ASCIIval], plotY-_lettersY[ASCIIval], Graphics.LEFT|Graphics.TOP);
            }
            if( _xPadding != null )
                plotX+=_charWidth+(_xPadding[ASCIIval])-_magicSpacing;
            else
                plotX+=_charWidth-_magicSpacing;
        }
        
        gC.setClip( clipX, clipY, clipW, clipH );                
    }
    
    public void drawChars(Graphics gC, char[] chars, int offset, int length, int plotX, int plotY) {        
        drawString( gC, String.valueOf( chars, offset, length ), plotX, plotY );   
    }
    
    public void setSpacing(int newSpacing) {
        _spacing=newSpacing;
    }
    
    public int getSpacing(){
        return _spacing -_magicSpacing;
    }
    
    public void setMagicSpacing( int newSpacing ){
        _magicSpacing = newSpacing;
    }
    
    public int getHeight(){
        return _charHeight;
    }
    
    public int getWidth(){
        return _charWidth;
    }
    
    public int getWidth( char c ){
        
        if( _xPadding != null )
            return _charWidth +(_xPadding[c])-_magicSpacing;
        else
            return _charWidth-_magicSpacing;
    }
    
    public int stringWidth( String text ){
        if( text == null )
            return 0;
                        
        int width = 0;
        
        if (_capsOnly)
            text = text.toUpperCase();
        
        byte charBytes[] = text.getBytes();
        int size = charBytes.length;
        
        int ASCIIval=0;
        for (int i=0; i<size; i++) {
            ASCIIval=(0|charBytes[i])&0xFF;
            
            if( _xPadding != null )
                width += _charWidth+(_xPadding[ASCIIval])-_magicSpacing;
            else
                width += _charWidth-_magicSpacing;
        }
        
        return width;
    }        
    
    public int charsWidth(char[] chars, int offset, int length) {
        return stringWidth( String.valueOf( chars, offset, length ) );
    }
    
    
}
